package rsaencrypt

import (
	"RSA/utils"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

// 通过提供的公钥文件，对明文内容进行加密
func Encrypt(PublicKeyFile string, PlainText io.Reader) (CipherBytes []byte, err error) {
	pubkeyfile, err := os.Open(PublicKeyFile)
	if err != nil {
		return nil, err
	}
	// 读取公钥文件内容
	pubkeyfilebytes, err := ioutil.ReadAll(pubkeyfile)
	if len(pubkeyfilebytes) >= 0 {
		if err != nil {
			return nil, err
		}
	} else {
		return nil, fmt.Errorf("This puklickey file is NULL!")
	}

	// 将公钥文件解析成block类型
	pubkeyblock, _ := pem.Decode(pubkeyfilebytes)
	if pubkeyblock == nil || pubkeyblock.Type != "RSA PUBLIC KEY" {
		return nil, fmt.Errorf("failed to decode PEM block containing public key")
	}

	// 提取公钥的值
	publicKey, err := x509.ParsePKCS1PublicKey(pubkeyblock.Bytes)
	if err != nil {
		return nil, err
	}

	// 将明文进行分割，每份长度为公钥的长度，但是有11个字符被padding占用
	partsize := publicKey.N.BitLen()/8 - 11

	// 需要加密的明文
	PlainTextBytes, _ := ioutil.ReadAll(PlainText)

	for _, v := range utils.SplitMsg(PlainTextBytes, partsize) {
		cipherbytes, _ := rsa.EncryptPKCS1v15(rand.Reader, publicKey, v)
		CipherBytes = append(CipherBytes, cipherbytes[:]...)
	}
	return CipherBytes, nil
}
